package com.spudtech.graphics
{
    
    import flash.geom.*;
    import flash.display.*;
    
    import com.spudtech.*;
    
    
    public class SpudGraphic extends SpudObject implements ISpudDrawable
    {
        
        protected var _graphic : DisplayObject;
        
        protected var _color  : uint;
        
        protected var _smooth : Boolean;
        
        public function SpudGraphic(init_graphic : DisplayObject,
                                    graphic_offset : Point,
                                    init_color : uint = 0xffffff)
        {
            super();
            
            _smooth = false;
            
            // Satisfy the setter
            _graphic = null;
            
            // Satisfy the setter
            _color = 0x000000;
            
            graphic = init_graphic;
            
            graphic.x = graphic_offset.x;
            graphic.y = graphic_offset.y;
            
            color = init_color;
            
        }
        
        
        public function get graphic() : DisplayObject
        {
            return _graphic;
        }
        public function set graphic(new_graphic : DisplayObject) : void
        {
            if (new_graphic == _graphic)
            {
                // This is already our graphic
                return;
            }
            
            if (_graphic != null)
            {
                // We already have a graphic
                // Detach it
                removeChild(_graphic);
            }
            
            _graphic = new_graphic;
            
            if (_graphic != null)
            {
                // We have a new graphic
                // Attach it
                addChild(new_graphic);
                
            }
            
        }
        
        public function get smooth() : Boolean
        {
            return _smooth;
        }
        public function set smooth(do_smooth : Boolean) : void
        {
            _smooth = do_smooth;
        }
        
        public function get color() : uint
        {
            return _color;
        }
        public function set color(new_color : uint) : void
        {
            if (new_color == _color)
            {
                // That is already our color
                return;
            }
            
            if (new_color > 0xffffff)
            {
                // The maximum value for a color
                // is 0xffffff
                // That color is pure white
                _color = 0xffffff;
            }
            else
            {
                // The color is in the
                // acceptable range
                _color = new_color;
            }
        }
        
        
        override public function render(offset : Matrix,
                                        clip_rect : Rectangle,
                                        draw_graphics : Graphics) : void
        {
            if (this.graphic == null)
            {
                throw new ReferenceError("Cannot draw a graphic object with null graphic data");
            }
            
            clip_rect.x += graphic.x;
            clip_rect.y += graphic.y;
            
            // Bitmap data for the graphic
            var bitmap_surface : BitmapData = new BitmapData(clip_rect.width,clip_rect.height,true,0x00000000);
            
            // Matrix transform for drawing
            // the graphic to the bitmap
            var to_bitmap_matrix : Matrix = new Matrix();
            
            // Translate by the graphic's position
            to_bitmap_matrix.translate(
                -(graphic.x),
                -(graphic.y));
            
            // Translate so that the rotation
            // is centered on the image
            to_bitmap_matrix.translate(
                (this.graphic.width / -2.0),
                (this.graphic.height / -2.0)
            )
            
            // Rotate the matrix
            // We get our total rotation, then
            // convert it into radians
            to_bitmap_matrix.rotate(
                    (this.totalRotation * (Math.PI / 180.0))
            );
            
            // Translate so that the rotation
            // is centered on the image
            to_bitmap_matrix.translate(
                (this.graphic.width / 2.0),
                (this.graphic.height / 2.0)
            );
            
            // Remove the graphic position
            // translate
            to_bitmap_matrix.translate(
                (graphic.x),
                (graphic.y)
            )
            
            
            // Translate the matrix to move
            // the image by the clip rect's
            // offset.
            // Basically, we are effectively
            // moving the clipping rectangle
            to_bitmap_matrix.translate(
                    -(clip_rect.x),
                    -(clip_rect.y)
            );
            
            
            bitmap_surface.draw(
                this,               // What to draw
                to_bitmap_matrix,   // Rotation and translation
                null,               // Color transform
                null,               // Blend mode
                null,               // Clip rect (We have our own)
                this.smooth         // Smoothing
            );
            
            
            // We might want to use that
            // offset matrix again later
            // for another render call
            // Because of that, we make
            // a clone of it to use in
            // this method
            var to_draw_matrix : Matrix = offset.clone();
            
            // The offset matrix will have
            // the graphic's position in
            // it, because, the position
            // that we need will be set
            // by whatever wants to render
            // the graphic
            // Because of that, we don't
            // want to translate the
            // offset matrix by our
            // position
            
            draw_graphics.beginBitmapFill(bitmap_surface,to_draw_matrix);
            
            draw_graphics.drawRect(
                offset.tx,
                offset.ty,
                clip_rect.width,
                clip_rect.height
            );
            
        }
        
    }
    
}
